﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IEx.Common;
using Microsoft.Practices.TransientFaultHandling;

namespace IEx.Model
{
    public class DeadlockStrategy : ITransientErrorDetectionStrategy
    {
        public bool IsTransient(Exception ex)
        {
            bool retry = false;
            if (ex != null)
            {
                SqlException ex2 = null;
                if ((ex2 = (ex as SqlException)) != null)
                {
                    int[] errorsToRetry = {
                        1205,  //Deadlock
                        -2,    //Timeout
                        2601  //primary key violation. Normally you wouldn't want to retry these, 
                              //but some procs in my database can cause it, because it's a crappy 
                              //legacy junkpile.
                    };

                    if (ex2.Errors.Cast<SqlError>().Any(err => errorsToRetry.Any(x => x == err.Number)))
                    {
                        retry = true;
                    }
                    else
                    {
                        throw ex;
                    }
                }

                if (ex is TimeoutException)
                    retry = true;
            }

#if DEBUG
            if (retry)
                Logger.Debug("===========>>>>> Deadlock appeared!");
#endif

            return retry;
        }
    }

    public class SqlRetryPolicy : RetryPolicy
    {
        /// <summary>
        /// Creates a new instance of <see cref="SqlRetryPolicy"/>. 
        /// The default retry limit is 5, which means that the total amount of time spent 
        /// between retries is 2 seconds plus the random factor.
        /// </summary>
        public SqlRetryPolicy()
            : base(new DeadlockStrategy(), 5, TimeSpan.FromSeconds(2))
        {
        }
    }
}
